package com.jeeplus.modules.common.excel.common.validator.impl;

import com.jeeplus.common.utils.StringUtil;
import com.jeeplus.modules.api.depart.entity.DepartManage;
import com.jeeplus.modules.api.depart.service.DepartManageService;
import com.jeeplus.modules.api.major.entity.Major;
import com.jeeplus.modules.api.major.service.MajorService;
import com.jeeplus.modules.common.excel.common.anno.MajorName;
import com.jeeplus.modules.common.excel.common.validator.abs.AbstractValidator;
import com.jeeplus.modules.common.utils.DictionaryUtils;
import com.jeeplus.modules.common.utils.SpringBeanUtils;
import com.jeeplus.modules.da.utils.XgDictUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 专业名称
 * @author wang.yishu
 */
public class MajorNameValidator extends AbstractValidator {

    private final static String key = "majorName";

    private final static String collegeKey = "collegeName";

    private DepartManageService departManageService;

    private MajorName majorName;

    private MajorService majorService;

    @Override
    public boolean canValidate(Field field) {
        majorName = field.getDeclaredAnnotation(MajorName.class);
        return majorName != null;
    }

    @Override
    public String toValidate(Object entity, Field field) {
        List<Map<String, Object>> dict = XgDictUtils.getDict("xg_education");
        Map<String, List<Object>> necessaryValidateData = this.chain.getNecessaryValidateData();
        List<Object> necessaryData = null;
        List<Object> collegeData = null;
        if (!necessaryValidateData.containsKey(key)) {
            majorService = SpringBeanUtils.getBean(MajorService.class);
            necessaryData = new ArrayList<>();
            Major majorParam = new Major();
            majorParam.setGradation("1,2,3,4,5");//层次：1本科,4专升本,5第二学位:
            List<Major> majorList = majorService.findList(majorParam);
            if (majorList != null && majorList.size() > 0) necessaryData.addAll(majorList);
            necessaryValidateData.put(key, necessaryData);
        } else {
            necessaryData = necessaryValidateData.get(key);
        }

        if (!necessaryValidateData.containsKey(collegeKey)) {
            collegeData = new ArrayList<>();
            departManageService = SpringBeanUtils.getBean(DepartManageService.class);
            DepartManage departManageParam = new DepartManage();
            departManageParam.setDepartmentType("1");//部门类型：1
            departManageParam.setState("1");//使用状态：1
            List<DepartManage> departManageList = departManageService.findList(departManageParam);
            if (departManageList != null && departManageList.size() > 0) collegeData.addAll(departManageList);
            necessaryValidateData.put(collegeKey, collegeData);
        } else {
            collegeData = necessaryValidateData.get(collegeKey);
        }
        String transformTo = majorName.transformTo();
        String forCodeFieldName = majorName.forCode();
        if (entity == null) return null;
        field.setAccessible(true);
        try {
            Object value = field.get(entity);
            Field forCodeField = entity.getClass().getDeclaredField(forCodeFieldName);
            forCodeField.setAccessible(true);
            String codeValueStr = (String) forCodeField.get(entity);
            if (value == null) return null;
            if (value instanceof String) {
                String majorNameStr = value.toString();
                String collegeNameStr = null;
                String collegeFieldName = majorName.forCollege();
                String forSchoolCodeFieldName = majorName.forSchoolCode();
                String gradationFieldName = majorName.forGradationLabel();
                String gradationLabelValue = null;
                String gradationCodeValue = null;
                String forSchoolCodeValue = null;
                if (StringUtil.isNotBlank(gradationFieldName)) {
                    Field gradationField = entity.getClass().getDeclaredField(gradationFieldName);
                    gradationField.setAccessible(true);
                    gradationLabelValue = (String) gradationField.get(entity);
                    if (StringUtil.isNotBlank(gradationLabelValue)) {
                        gradationCodeValue = DictionaryUtils.getDictValue("xg_education", gradationLabelValue, dict);
                    }
                }
                if (StringUtil.isNotBlank(forSchoolCodeFieldName)) {
                    Field forSchoolCodeField = entity.getClass().getDeclaredField(forSchoolCodeFieldName);
                    forSchoolCodeField.setAccessible(true);
                    forSchoolCodeValue = (String) forSchoolCodeField.get(entity);
                }
                if (StringUtil.isNotBlank(collegeFieldName)) {
                    Field collegeNameField = entity.getClass().getDeclaredField(collegeFieldName);
                    collegeNameField.setAccessible(true);
                    Object collegeNameValue = collegeNameField.get(entity);
                    if (collegeNameValue != null) collegeNameStr = collegeNameValue.toString();
                }
                String finalCollegeNameStr = collegeNameStr;
                DepartManage college = null;
                if (StringUtil.isNotBlank(collegeNameStr)) {
                    List<Object> collegeList = collegeData.stream().filter(obj -> ((DepartManage) obj).getName().equals(finalCollegeNameStr)).collect(Collectors.toList());
                    if (collegeList.size() > 0) {
                        college = (DepartManage) collegeList.get(0);
                    }
                }
                String finalForSchoolCodeValue = forSchoolCodeValue;
                String finalGradationCodeValue = gradationCodeValue;
                Major major = null;
                List<Object> majorList = null;
                if (college != null) {
                    DepartManage finalCollege = college;
                    majorList = necessaryData.stream().filter(obj -> ((Major) obj).getCollege().equals(finalCollege.getId()) && ((Major) obj).getMajorName().equals(majorNameStr) && (!StringUtil.isNotBlank(codeValueStr) || codeValueStr.equals(((Major) obj).getMajorNumber()))
                    && ((!StringUtil.isNotBlank(finalForSchoolCodeValue)) || (((Major) obj).getSchoolMajorNumber() == null || ((Major) obj).getSchoolMajorNumber().equals("")) || finalForSchoolCodeValue.equals(((Major) obj).getSchoolMajorNumber()))
                            && (StringUtil.isBlank(finalGradationCodeValue) || (((Major) obj).getGradation() == null || ((Major) obj).getGradation().equals("")) || finalGradationCodeValue.equals(((Major) obj).getGradation()))).collect(Collectors.toList());
                } else {

                    majorList = necessaryData.stream().filter(obj -> ((Major) obj).getMajorName().equals(majorNameStr) && (!StringUtil.isNotBlank(codeValueStr) || codeValueStr.equals(((Major) obj).getMajorNumber())) &&
                            ((!StringUtil.isNotBlank(finalForSchoolCodeValue)) || (((Major) obj).getSchoolMajorNumber() == null || ((Major) obj).getSchoolMajorNumber().equals("")) || finalForSchoolCodeValue.equals(((Major) obj).getSchoolMajorNumber()))
                            && (StringUtil.isBlank(finalGradationCodeValue) || (((Major) obj).getGradation() == null || ((Major) obj).getGradation().equals("")) || finalGradationCodeValue.equals(((Major) obj).getGradation()))).collect(Collectors.toList());
                }
                if (majorList.size() > 0) {
                    major = (Major) majorList.get(0);
                    if (StringUtil.isNotBlank(transformTo)) {
                        Field transformToField = entity.getClass().getDeclaredField(transformTo);
                        transformToField.setAccessible(true);
                        if (transformToField.getType().getName().equals(String.class.getName())) {
                            transformToField.set(entity, major.getId());
                        } else if(transformToField.getType().getName().equals(Integer.class.getName())){
                            transformToField.set(entity, Integer.valueOf(major.getId()));
                        }
                    }
                } else {
                    return majorName.msg();
                }
            }
        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }
        return null;
    }
}
